import ast
import logging
import os.path
import re
import traceback

from collections import OrderedDict, Sized, Mapping
from functools import reduce
from itertools import tee, count
from textwrap import dedent

import itertools
from lxml import etree, html
from psycopg2.extensions import TransactionRollbackError
import werkzeug
from werkzeug.utils import escape as _escape

from odoo.tools import pycompat, freehash, wrap_values

try:
    import builtins
    builtin_defaults = {name: getattr(builtins, name) for name in dir(builtins)}
except ImportError:
    pass

try:
    import astor
except ImportError:
    astor = None

from odoo.tools.parse_version import parse_version

unsafe_eval = eval

_logger = logging.getLogger(__name__)

arg = getattr(ast, 'arg', lambda arg, annotation: ast.Name(id=arg, ctx=ast.Param()))

arguments = ast.arguments

if pycompat.PY2:
    pass

class Contextifier(ast.NodeTransformer):

    def __init__(self, params=()):
        pass

    def visit_Name(self, node):
        pass

    def visit_Lambda(self, node):
        pass

    def _visit_comp(self, node):
        pass

    visit_GeneratorExp = visit_ListComp = visit_SetComp = visit_DictComp = _visit_comp

class QWebException(Exception):
    def __init__(self, message, error=None, path=None, html=None, name=None, astmod=None):
        pass

    def __str__(self):
        pass

    def __repr__(self):
        pass

escape = (lambda text: _escape(text, quote=True)) if parse_version(getattr(werkzeug, '__version__', '0.0')) < parse_version('0.9.0') else _escape

def foreach_iterator(base_ctx, enum, name):
    pass

_FORMAT_REGEX = re.compile(
    r'(?:#\{(.+?)\})|(?:\{\{(.+?)\}\})')

class frozendict(dict):
    def __delitem__(self, key):
        pass
    def __setitem__(self, key, val):
        pass
    def clear(self):
        pass
    def pop(self, key, default=None):
        pass
    def popitem(self):
        pass
    def setdefault(self, key, default=None):
        pass
    def update(self, *args, **kwargs):
        pass
    def __hash__(self):
        return hash(frozenset((key, freehash(val)) for key, val in self.items()))

class QWeb(object):
    _void_elements = frozenset([
        'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
        'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'])
    _name_gen = count()

    def render(self, template, values=None, **options):
        pass

    def compile(self, template, options):
        pass

    def default_values(self):
        pass

    def get_template(self, template, options):
        pass

    def load(self, template, options):
        pass

    def format(self, value, formating, *args, **kwargs):
        pass

    def _profiling(self, astmod, options):
        pass

    def _base_module(self):
        pass

    def _create_def(self, options, body, prefix='fn', lineno=None):
        pass

    def _call_def(self, name, append='append', values='values'):
        pass

    def _append(self, item):
        pass

    def _extend(self, items):
        pass

    def _if_content_is_not_Falsy(self, body, orelse):
        pass

    def _make_name(self, prefix='var'):
        pass

    def _compile_node(self, el, options):
        pass

    def _compile_directives(self, el, options):
        pass

    def _values_var(self, varname, ctx):
        pass

    def _append_attributes(self):
        pass

    def _directives_eval_order(self):
        pass

    def _is_static_node(self, el, options):
        pass

    def _compile_static_node(self, el, options):
        pass

    def _compile_static_attributes(self, el, options):
        pass

    def _compile_dynamic_attributes(self, el, options):
        pass

    def _compile_all_attributes(self, el, options, attr_already_created=False):
        pass

    def _compile_tag(self, el, content, options, attr_already_created=False):
        pass

    def _compile_directive_debug(self, el, options):
        pass

    def _compile_directive_tag(self, el, options):
        pass

    def _compile_directive_set(self, el, options):
        pass

    def _compile_directive_content(self, el, options):
        pass

    def _compile_directive_else(self, el, options):
        pass

    def _compile_directive_elif(self, el, options):
        pass

    def _compile_directive_if(self, el, options):
        pass

    def _compile_directive_groups(self, el, options):
        pass

    def _compile_directive_foreach(self, el, options):
        pass

    def _compile_tail(self, el):
        pass

    def _compile_directive_esc(self, el, options):
        pass

    def _compile_widget(self, el, expression, field_options):
        pass

    def _compile_widget_options(self, el):
        pass

    def _compile_directive_field(self, el, options):
        pass

    def _compile_widget_value(self, el, options):
        pass

    def _compile_directive_call(self, el, options):
        pass

    def _get_dynamic_att(self, tagName, atts, options, values):
        pass

    def _post_processing_att(self, tagName, atts, options):
        pass

    def _get_field(self, record, field_name, expression, tagName, field_options, options, values):
        pass

    def _get_widget(self, value, expression, tagName, field_options, options, values):
        pass

    def _compile_strexpr(self, expr):
        pass

    def _compile_expr0(self, expr):
        pass

    def _compile_format(self, f):
        pass

    def _compile_expr(self, expr):
        pass
